<?php

namespace App\Models\Traits;

use App\Enums\ApplyStatus;
use App\Events\ApplyStatusChangedEvent;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;

trait HasEasyApply
{
    public function initializeHasEasyApply(): void
    {
        $this->withCasts([
            'apply_status' => ApplyStatus::class,
            'passed_at' => 'datetime',
            'rejected_at' => 'datetime',
        ]);
    }

    /**
     * Notes   : 申请中
     *
     * @Date   : 2024/1/15 9:25
     * @Author : <Jason.C>
     * @param  Builder  $query
     * @return Builder
     */
    public function scopeOfInited(Builder $query): Builder
    {
        return $query->where('apply_status', ApplyStatus::INIT);
    }

    /**
     * Notes   : 审核中
     *
     * @Date   : 2024/1/15 9:25
     * @Author : <Jason.C>
     * @param  Builder  $query
     * @return Builder
     */
    public function scopeOfReviewed(Builder $query): Builder
    {
        return $query->where('apply_status', ApplyStatus::REVIEW);
    }

    /**
     * Notes   : 已通过审核
     *
     * @Date   : 2024/1/15 9:25
     * @Author : <Jason.C>
     * @param  Builder  $query
     * @return Builder
     */
    public function scopeOfPassed(Builder $query): Builder
    {
        return $query->where('apply_status', ApplyStatus::PASS);
    }

    /**
     * Notes   : 驳回
     *
     * @Date   : 2024/1/15 9:25
     * @Author : <Jason.C>
     * @param  Builder  $query
     * @return Builder
     */
    public function scopeOfRejected(Builder $query): Builder
    {
        return $query->where('apply_status', ApplyStatus::REJECT);
    }

    /**
     * Notes   : 是否已通过
     *
     * @Date   : 2024/1/15 9:26
     * @Author : <Jason.C>
     * @return bool
     */
    public function isPassed(): bool
    {
        return $this->apply_status === ApplyStatus::PASS;
    }

    /**
     * Notes   : 是否未通过审核
     *
     * @Date   : 2024/1/15 9:26
     * @Author : <Jason.C>
     * @return bool
     */
    public function isNotPassed(): bool
    {
        return $this->apply_status !== ApplyStatus::PASS;
    }

    /**
     * Notes   : 关联审核人
     *
     * @Date   : 2024/1/15 9:26
     * @Author : <Jason.C>
     * @return MorphTo
     */
    public function reviewer(): MorphTo
    {
        return $this->morphTo();
    }

    /**
     * Notes   : 审核通过操作
     *
     * @Date   : 2024/1/12 18:02
     * @Author : <Jason.C>
     * @param  Model  $user
     * @return bool
     */
    public function pass(Model $user): bool
    {
        if (in_array($this->apply_status, [ApplyStatus::PASS, ApplyStatus::REJECT])) {
            return false;
        }

        $this->reviewer_type = $user->getMorphClass();
        $this->reviewer_id = $user->getKey();
        $this->apply_status = ApplyStatus::PASS;
        $this->passed_at = now();

        $save = $this->save();
        if ($save) {
            ApplyStatusChangedEvent::dispatch($this, ApplyStatus::PASS);
        }

        return $save;
    }

    /**
     * Notes   : 驳回操作
     *
     * @Date   : 2024/1/12 18:02
     * @Author : <Jason.C>
     * @param  Model  $user
     * @param  string|null  $reason
     * @return bool
     */
    public function reject(Model $user, string $reason = null): bool
    {
        if (in_array($this->apply_status, [ApplyStatus::PASS, ApplyStatus::REJECT])) {
            return false;
        }

        $this->reviewer_type = $user->getMorphClass();
        $this->reviewer_id = $user->getKey();
        $this->apply_status = ApplyStatus::REJECT;
        $this->reject_reason = $reason;
        $this->rejected_at = now();

        $save = $this->save();
        if ($save) {
            ApplyStatusChangedEvent::dispatch($this, ApplyStatus::REJECT);
        }

        return $save;
    }
}
